package org.fastsyncer.common.util;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipArchiveInputStream;
import org.apache.commons.compress.utils.IOUtils;
import org.apache.commons.io.FileUtils;

public class ZipUtil {

    public static final int BUFFER_SIZE = 1024;

    /**
     * 解压 zip 文件
     * @param tarDir zip 压缩文件
     * @param destDir zip 压缩文件解压后保存的目录
     * @return 返回 zip 压缩文件里的文件名的 list
     * @throws Exception
     */
    public static List<String> unZip(String tarDir, String destDir) throws Exception {
        File zipFile = FileUtils.getFile(tarDir);
        // 如果 destDir 为 null, 空字符串, 或者全是空格, 则解压到压缩文件所在目录
        if(null == destDir || "".equals(destDir)) {
            destDir = zipFile.getParent();
        }
        destDir = destDir.endsWith(File.separator) ? destDir : destDir + File.separator;
        
        //流
        FileInputStream fis = null;
        BufferedInputStream bis = null;
        ZipArchiveInputStream is = null;
        
        List<String> fileNames = new ArrayList<String>();
        try {
            fis = new FileInputStream(zipFile);
            bis = new BufferedInputStream(fis, BUFFER_SIZE);
            is = new ZipArchiveInputStream(bis);
            ZipArchiveEntry entry = null;

            while ((entry = is.getNextZipEntry()) != null) {
                fileNames.add(entry.getName());

                if (entry.isDirectory()) {
                    File directory = new File(destDir, entry.getName());
                    directory.mkdirs();
                } else {
                    FileOutputStream fos = null;
                    OutputStream os = null;
                    try {
                        fos = new FileOutputStream(new File(destDir, entry.getName()));
                        os = new BufferedOutputStream(fos, BUFFER_SIZE);
                        IOUtils.copy(is, os);
                    } finally {
                        if(os!=null){
                            os.close();
                        }
                        if(fos!=null){
                            fos.close();
                        }
                    }
                }
            }
        } catch(Exception e) {
        } finally {
            if(is!=null){
                is.close();
            }
            if(bis!=null){
                bis.close();
            }
            if(fis!=null){
                fis.close();
            }
        }
        return fileNames;
    }

}
